---
sidebar_label: Manage Metadata
sidebar_position: 20
description: Manage Metadata with the Hasura Metadata API
keywords:
  - hasura
  - docs
  - Metadata API
  - API reference
  - metadata
toc_max_heading_level: 2
---

# Metadata API Reference: Manage Metadata

## Introduction

APIs for managing Hasura Metadata which is stored in the `hdb catalog` schema.

:::tip Supported from

The Metadata API is supported for versions `v2.0.0` and above and
replaces the older [schema/Metadata API](/api-reference/schema-metadata-api/index.mdx).

:::

## export_metadata {#metadata-export-metadata}

`export_metadata` is used to export the current Metadata from the server as a JSON file.

```http
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type" : "export_metadata",
    "version": 1 | 2
    "args": {}
}
```

Response:

The response JSON will be the Metadata object. The structure of the
Metadata object is just a JSON version of the
[Metadata files](/migrations-metadata-seeds/metadata-format.mdx) generated by the CLI.

V2 Example:

```http
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
     "type": "export_metadata",
     "version": 2,
     "args": {}
}
```

Response:

```json
{
    "resource_version": 8,
    "metadata": {
        "version": 3,
        "sources": [
        {
            "name": "default",
            "tables": [
            {
                "table": {
                 ...
```

## replace_metadata {#metadata-replace-metadata}

`replace_metadata` is used to replace/import Metadata into Hasura.
Existing Metadata will be replaced with the new one.

```http
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type" : "replace_metadata",
    "version": 1 | 2
    "args": <replace-metadata-args>
}
```

### Args syntax {#metadata-replace-metadata-syntax}

If version is set to 1, then args should be the JSON object which is
same as the output of [export_metadata](#metadata-export-metadata).

For version 2, the following structure is used:

```json
{
    allow_inconsistent_metadata: Boolean,
    allow_warnings: Boolean,
    metadata: metadata-object
}
```

| Key                         | Required | Schema                                       | Description                                                                                                                           |
| --------------------------- | -------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| allow_inconsistent_metadata | false    | Boolean                                      | If set to `true`, Metadata will be replaced with a warning in the response indicating which items are inconsistent (default: `false`) |
| allow_warnings              | false    | Boolean                                      | If set to `false`, any warnings will cause the metadata API call to fail (default: `true`)                                            |
| metadata                    | true     | [export_metadata](#metadata-export-metadata) | The Metadata that will replace the current metadata.                                                                                  |

If the version is not specified, then it is inferred from the format of `args`.

### Request

```http
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type" : "replace_metadata",
    "version": 2
    "args": {
      "allow_inconsistent_metadata": Boolean,
      "allow_warnings": Boolean,
      "metadata": <metadata-object>
    }
}
```

### Responses

Version 2 with inconsistencies and allow_inconsistent_metadata=false, or
omitted corresponds with the response document in
[replace_metadata](#metadata-replace-metadata).

Version 2 example with inconsistencies and
allow_inconsistent_metadata=true includes an `is_consistent` and
`inconsistent_objects` corresponding to
[get_inconsistent_metadata](#metadata-get-inconsistent-metadata).

```http
HTTP/1.1 400 Bad Request

{
  "internal": [
    {
      "type": "remote_schema",
      "reason": "HTTP exception occurred while sending the request to http://localhost:5000/hello-graphql",
      "definition": {
        "definition": {
          "url": "http://localhost:5000/hello-graphql",
          "forward_client_headers": false
        },
        "name": "test",
        "permissions": [],
        "comment": "testing replace metadata with Remote Schemas"
      }
    }, ...
  ]
}
```

Version 2 example with inconsistencies and
allow_inconsistent_metadata=true:

```http
HTTP/1.1 200 OK

{
  "is_consistent": false,
  "inconsistent_objects": [
      {
      "definition": {
          "definition": {
          "url": "http://localhost:5000/hello-graphql",
          "forward_client_headers": false
          },
          "name": "test",
          "permissions": [],
          "comment": "testing replace metadata with Remote Schemas"
      },
      "reason": "HTTP exception occurred while sending the request to http://localhost:5000/hello-graphql",
      "type": "remote_schema"
      }, ...
```

Version 2 example with invalid `resource_version`:

```http
HTTP/1.1 409 Conflict

{
  "path": "$",
  "error": "metadata resource version referenced (2) did not match current version",
  "code": "conflict"
}
```

Version 2 example with warnings allow_warnings=true

```http
HTTP/1.1 200 OK

{
  "is_consistent": true,
  "inconsistent_objects": [],
  "warnings: [
    {
      "code": "illegal-event-trigger-name",
      "message": "The event trigger with name \"weird]name]\" may not work as expected, hasura suggests to use only alphanumeric, underscore and hyphens in an event trigger name",
      "type": "event_trigger",
      "name": "event_trigger weird]name] in table hasura.authors in source mssql"
    },
    ...
  ]
}
```

Version 2 example with warnings allow_warnings=false

```http
HTTP/1.1 400 Bad Request

{
  "code": "metadata-warnings",
  "error": "failed due to metadata warnings",
  "internal": [
    {
      "code": "illegal-event-trigger-name",
      "message": "The event trigger with name \"weird]name]\" may not work as expected, hasura suggests to use only alphanumeric, underscore and hyphens in an event trigger name",
      "name": "event_trigger weird]name] in table hasura.authors in source mssql",
      "type": "event_trigger"
    }
  ],
  "path": "$.args"
}
```

## reload_metadata {#metadata-reload-metadata}

`reload_metadata` should be used when there is a change in underlying
Postgres database that Hasura should be aware of. Example: a new column
is added to a table using `psql` and this column should now be added to
the GraphQL schema.

```http
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type" : "reload_metadata",
    "args": {
        "reload_remote_schemas": true,
        "reload_sources": false,
        "recreate_event_triggers": true
    }
}
```

Response:

If the Metadata is consistent:

```json
{
  "is_consistent": true,
  "message": "success"
}
```

If the Metadata is not consistent:

```json
{
  "is_consistent": false,
  "message": "success",
  "inconsistent_objects": [
    {
      "definition": {
        "schema": "public",
        "name": "article"
      },
      "name": "table article in source default",
      "reason": "Inconsistent object: no such table/view exists in source: \"article\"",
      "type": "table"
    }
  ]
}
```

### Args syntax {#metadata-reload-metadata-syntax}

| Key                     | Required | Schema                                                                               | Description                                                                                                                                                                                                                                                                                                                                                                                              |
| ----------------------- | -------- | ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| reload_remote_schemas   | false    | `Boolean` \| \[[RemoteSchemaName](/api-reference/syntax-defs.mdx#remoteschemaname)\] | If set to `true`, all Remote Schemas' (including inconsistent ones) cached GraphQL schemas are refreshed (default: `true`)                                                                                                                                                                                                                                                                               |
| reload_sources          | false    | `Boolean` \| \[[SourceName](/api-reference/syntax-defs.mdx#sourcename)\]             | If set to `true`, all sources' (including inconsistent ones) cached GraphQL schemas are refreshed (default: `true`)                                                                                                                                                                                                                                                                                      |
| recreate_event_triggers | false    | `Boolean` \| \[[SourceName](/api-reference/syntax-defs.mdx#sourcename)\]             | If set to `true`, all sources' (including inconsistent ones) cached Event Triggers and their corresponding SQL triggers present in the source database will be recreated. When an array of [SourceName](/api-reference/syntax-defs.mdx#sourcename) is provided, the Event Triggers will only be recreated for those sources. (default: <em>false</em> i.e. no sources' Event Triggers will be recreated) |

## clear_metadata {#metadata-clear-metadata}

`clear_metadata` can be used to reset the state of Hasura -- clean the
current state by forgetting the tables tracked, relationships,
permissions, Event Triggers etc.

```http
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type" : "clear_metadata",
    "args": {}
}
```

## get_inconsistent_metadata {#metadata-get-inconsistent-metadata}

`get_inconsistent_metadata` can be used to fetch all inconsistent Metadata objects.

```http
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type": "get_inconsistent_metadata",
    "args": {}
}
```

Response:

```json
{
  "is_consistent": false,
  "inconsistent_objects": [
    {
      "type": "table",
      "name": "table public.article in source default",
      "definition": {
        "schema": "public",
        "name": "article"
      },
      "reason": "Inconsistent object: no such table/view exists in source: \"public.article\""
    },
    {
      "type": "array_relation",
      "name": "array_relation articles in table public.author in source default",
      "definition": {
        "name": "articles",
        "source": "default",
        "comment": null,
        "table": {
          "schema": "public",
          "name": "author"
        },
        "using": {
          "foreign_key_constraint_on": {
            "column": "author_id",
            "table": {
              "schema": "public",
              "name": "article"
            }
          }
        }
      },
      "reason": "Inconsistent object: in table \"public.author\": in relationship \"articles\": table \"public.article\" does not exist"
    }
  ]
}
```

## drop_inconsistent_metadata {#metadata-drop-inconsistent-metadata}

`drop_inconsistent_metadata` can be used to purge all inconsistent
objects from the metadata.

```http
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type": "drop_inconsistent_metadata",
    "args": {}
}
```

## test_webhook_transform {#test-webhook-transform}

`test_webhook_transform` can be used to test out request transformations using mock data.

```http
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type" : "test_webhook_transform",
    "args" : {
      "webhook_url": "http://localhost:1234",
      "request_headers": [["myKey", "myValue"]],
      "body": { "hello": "world" },
      "request_transform": {
        "body": "{{ $body.world }}",
        "template_engine": "Kriti"
      }
    }
}
```

The _webhook_url_ can be provided in an Environment Variable supplied in an object with the _from_env_ key:

```http
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
    "type" : "test_webhook_transform",
    "args" : {
      "webhook_url": {"from_env": "url_env_var" },
      "request_headers": [["myKey", "myValue"]],
      "body": { "hello": "world" },
      "request_transform": {
        "body": "{{ $body.world }}",
        "template_engine": "Kriti"
      }
    }
}
```
